<template>
  <div class="flex-col">
    <div class="flex-row justify-center" style="margin-bottom: 10px">
      <!-- 纸张大小 A3、A4 等 -->
      <div class="paper">
        <el-button-group class="ml-4">
          <template v-for="(value, type) in paperTypes" :key="type">
            <el-button @click="setPaper(type, value)" :type="curPaperType === type ? 'primary' : ''">
              {{ type }}
            </el-button>
          </template>
          <el-button @click="showPaperPop" :type="curPaperType === 'other' ? 'primary' : ''">
            自定义纸张
          </el-button>
        </el-button-group>

        <div class="popover">
          <div class="popover-content flex-col" v-show="paperPopVisible">
            <div style="font-size: 16px; font-weight: bold">
              设置纸张宽高(mm)
            </div>
            <div class="flex-row mt-10">
              <input class="input" v-model="paperWidth" type="number" placeholder="宽(mm)" />
              <span class="ml-10 mr-10">x</span>
              <input class="input" v-model="paperHeight" type="number" placeholder="高(mm)" />
            </div>
            <el-button style="margin-top: 6px" type="primary" @click.stop="setPaperOther">
              确定
            </el-button>
          </div>
        </div>
      </div>
      <!-- 缩放 -->
      <div class="flex-row align-center ml-10">
        <el-button style="width: 32px; height: 32px; font-size: 20px; padding: 0" :icon="ZoomOut"
          @click="changeScale(false)" />

        <div style="margin: 0 4px; width: 40px">
          {{ (scaleValue * 100).toFixed(0) }}%
        </div>
        <el-button style="width: 32px; height: 32px; font-size: 20px; padding: 0" :icon="ZoomIn"
          @click="changeScale(true)" />
      </div>
      <!-- 按钮组 -->
      <div>
        <el-button type="warning" style="margin-left: 8px" @click.stop="rotatePaper">
          旋转纸张(宽高互换)
        </el-button>
        <el-button type="danger" @click.stop="clearPaper"> 清空纸张 </el-button>
        <el-button type="primary" :icon="View" @click="preview">
          预览
        </el-button>
        <el-button type="primary" :icon="Document" @click.stop="exportJson">
          保存模板
        </el-button>
        <el-button type="primary" :icon="Printer" @click.stop="print">
          浏览器打印
        </el-button>
        <!-- <button class="warning circle-10 ml-10" @click.stop="print2">
        直接打印(需要连接客户端)
        <i class="iconfont sv-printer" />
      </button> -->
      </div>
    </div>
    <div class="flex-row" style="height: 87vh">
      <div class="flex-2 left flex-col">
        <div class="title">默认样式</div>
        <div id="provider-container1" class="container rect-printElement-types"></div>
        <div class="title">自定义样式</div>
        <!-- provider2 的容器; -->
        <!-- 这里自定义显示样式 custom-style-types -->
        <div id="provider-container2" class="container custom-style-types"></div>
        <div class=""></div>
      </div>
      <div class="flex-5 center">
        <!-- 设计器的 容器 -->
        <div id="hiprint-printTemplate"></div>
      </div>
      <div class="flex-2 right">
        <!-- 元素参数的 容器 -->
        <div id="PrintElementOptionSetting"></div>
      </div>
    </div>
  </div>
  <el-dialog v-model="dialogModel" title="模板名称" width="300">
    <el-input v-model="addData.title" style="width: 100%" clearable placeholder="请输入模板名称" />
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogModel = false">取消</el-button>
        <el-button type="primary" @click="submit"> 确定 </el-button>
      </div>
    </template>
  </el-dialog>
  <print-preview ref="preView" />
</template>

<script>
export default {
  name: "start-02",
};
</script>

<script setup>
import {
  ZoomIn,
  ZoomOut,
  View,
  Printer,
  Document,
} from "@element-plus/icons-vue";
import {
  onMounted,
  ref,
  getCurrentInstance,
  computed,
  reactive,
  onUnmounted,
} from "vue";
import { ElMessage } from "element-plus";
import { hiprint } from "vue-plugin-hiprint";
import { provider1 } from "./provider1";
import { provider2 } from "./provider2";
import template from "./empty";
import printData from "./printData";
import { useZoom } from "./use-zoom";
import printPreview from "./preview.vue";
import { addModel, updateModel } from "@/api/list.js";
// 工具
import { newHiprintPrintTemplate } from "./template-helper";
import { getHiprintPrintTemplate } from "./template-helper";


import { useRoute } from "vue-router";
const route = useRoute();
const model = ref(null);
const tmp = ref([]);

if (route.query.data) {
  console.log(route.query.data);
  if (JSON.parse(route.query.data).modelStr.length > 99) {
    model.value = JSON.parse(route.query.data);
    tmp.value = JSON.parse(model.value.modelStr);
  } else {
    tmp.value = template;
  }
} else {
  console.log(model.value);
  tmp.value = template;
}
const loading = ref(false);
const dialogVisible = ref(false);
const dialogModel = ref(false);
const TEMPLATE_KEY = getCurrentInstance().type.name; // 存储模板对象的 key

const { scaleValue, changeScale } = useZoom(TEMPLATE_KEY);

const paperPopVisible = ref(false);
const showPaperPop = () => {
  paperPopVisible.value = true;
};
const tp = () => {
  return getHiprintPrintTemplate(TEMPLATE_KEY);
};
const state = reactive({
  curPaper: {
    type: "A4",
    width: 210,
    height: 296.6,
  },
});
const paperWidth = ref("220");
const paperHeight = ref("180");
const setPaper = (type, value) => {
  try {
    if (Object.keys(paperTypes.value).includes(type)) {
      state.curPaper = { type: type, width: value.width, height: value.height };
      tp().setPaper(value.width, value.height);
    } else {
      state.curPaper = {
        type: "other",
        width: value.width,
        height: value.height,
      };
      tp().setPaper(value.width, value.height);
    }
  } catch (error) {
    alert(`操作失败: ${error}`);
  }
};
const setPaperOther = () => {
  let value = {};

  value.width = paperWidth.value;
  value.height = paperHeight.value;
  console.log(value, paperWidth.value, paperHeight.value);
  paperPopVisible.value = false;
  setPaper("other", value);
};
const paperTypes = ref({
  A3: {
    width: 420,
    height: 296.6,
  },
  A4: {
    width: 210,
    height: 296.6,
  },
  A5: {
    width: 210,
    height: 147.6,
  },
  B3: {
    width: 500,
    height: 352.6,
  },
  B4: {
    width: 250,
    height: 352.6,
  },
  B5: {
    width: 250,
    height: 175.6,
  },
});
const curPaperType = computed(() => {
  let type = "other";
  let types = paperTypes.value;
  for (const key in types) {
    let item = types[key];
    let { width, height } = state.curPaper;
    if (item.width === width && item.height === height) {
      type = key;
    }
  }
  return type;
});
// 自定义传入 provider 的参数
let options = {
  config: {
    tid: "providerModule1.config",
    title: "参数示例",
    type: "text",
    options: {
      testData: "单据表头",
      height: 30,
      fontSize: 16,
    },
  },
};
// 初始化 provider
hiprint.init({
  providers: [provider1(options), provider2(options)],
});
/**
 * 这里必须要在 onMounted 中去构建 左侧可拖拽元素 或者 设计器
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 */
const closePaper = () => {
  if (
    !event.target.closest("button") &&
    !event.target.closest(".popover-content")
  ) {
    paperPopVisible.value = false;
  }
};
onMounted(() => {
  buildLeftElement();
  buildDesigner();
  document.addEventListener("click", closePaper);
});
onUnmounted(() => {
  document.removeEventListener("click", closePaper);
});
/**
 * 构建左侧可拖拽元素
 * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
 * 调用之前 可以先 console.log($("#hiprint-printTemplate")) 看看是否有该 dom
 */
const buildLeftElement = () => {
  // ----- providerModule1 -----
  // eslint-disable-next-line no-undef
  $("#provider-container1").empty(); // 先清空, 避免重复构建
  // eslint-disable-next-line no-undef
  hiprint.PrintElementTypeManager.build(
    $("#provider-container1"),
    "providerModule1"
  );
  // ----- providerModule2 -----
  // eslint-disable-next-line no-undef
  $("#provider-container2").empty(); // 先清空, 避免重复构建
  // eslint-disable-next-line no-undef
  hiprint.PrintElementTypeManager.build(
    $("#provider-container2"),
    "providerModule2"
  );
};
/**
 * 构建设计器
 * 注意: 必须要在 onMounted 中去构建
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 */
let hiprintTemplate;
// ref 创建的模板json
const templateRef = ref(tmp);
console.log("templateRef", templateRef);
console.log("templateRef.value", templateRef.value);
const buildDesigner = () => {
  $("#hiprint-printTemplate").empty(); // 先清空, 避免重复构建
  hiprintTemplate = newHiprintPrintTemplate(TEMPLATE_KEY, {
    template: templateRef.value, // 模板
    settingContainer: "#PrintElementOptionSetting", // 元素参数容器
  });
  // 构建 并填充到 容器中
  hiprintTemplate.design("#hiprint-printTemplate");
};
/**
 * 浏览器打印
 */
const print = () => {
  // 参数: 打印时设置 左偏移量，上偏移量
  let options = { leftOffset: -1, topOffset: -1 };
  // 扩展
  let ext = {
    callback: () => {
      console.log("浏览器打印窗口已打开");
    },
    styleHandler: () => {
      // 重写 文本 打印样式
      return "<style>.hiprint-printElement-text{color:red !important;}</style>";
    },
  };
  // 调用浏览器打印
  hiprintTemplate.print(printData, options, ext);
};
/**
 * 直接打印: 借助客户端,静默打印(无弹窗直接打印)
 * 注意: 需要先连接客户端
 */
// const print2 = () => {
//   if (hiprint.hiwebSocket.opened) {
//     hiprintTemplate.print2(printData);
//   } else {
//     alert("请先连接客户端(刷新网页), 然后再点击「直接打印」");
//   }
// };
// ----------------- 模板对象 api 部分 -----------------
/**
 * 旋转纸张
 */
const rotatePaper = () => {
  hiprintTemplate.rotatePaper();
};
const preView = ref(null);
const preview = () => {
  let { width } = state.curPaper;
  preView.value.show(hiprintTemplate, printData, width);
};
/**
 * 清空所有元素
 */
const clearPaper = () => {
  hiprintTemplate.clear();
};
/**
 * 导出模板 json
 * 必须确保 hiprintTemplate 已成功创建
 */
const addData = ref({
  id: "",
  title: undefined,
  isDefault: "0",
  modelStr: "",
  createTime: getDate(),
});
const exportJson = async () => {
  if (model.value) {
    //从列表中过来 直接更新
    addData.value.id = model.value.id;
    addData.value.title = model.value.title;
    // console.log(addData.value);
    let json = JSON.stringify(hiprintTemplate.getJson());
    addData.value.modelStr = json;
    const res = await updateModel(addData.value);
    console.log(res, "res");
    if (res.status == 200) {
      ElMessage.success("修改成功");
    } else {
      ElMessage.error("修改失败");
    }
  } else {
    //新增
    dialogModel.value = true;
  }
};
const submit = async () => {
  let json = JSON.stringify(hiprintTemplate.getJson());
  addData.value.modelStr = json;
  const res = await addModel(addData.value);
  dialogModel.value = false;
  if (res.status == 201) {
    ElMessage.success("新增成功");
  } else {
    ElMessage.error("新增失败");
  }
};
/**
 * 导出模板 json tid
 * 仅导出 options, 不导出 printElementType
 * 必须确保 hiprintTemplate 已成功创建
 */
//  const exportJsonTid = () => {
//   let json = hiprintTemplate.getJsonTid();
//   console.log(json);
//   alert("导出成功! 请查看控制台输出");
// };
function getDate() {
  const date = new Date();
  // 获取当前时间的各个部分
  const year = date.getFullYear(); // 年份
  const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份，从 0 开始，所以需要加 1
  const day = String(date.getDate()).padStart(2, "0"); // 日期
  const hours = String(date.getHours()).padStart(2, "0"); // 小时
  const minutes = String(date.getMinutes()).padStart(2, "0"); // 分钟
  const seconds = String(date.getSeconds()).padStart(2, "0"); // 秒

  // 手动拼接字符串
  const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  return formattedDate;
}
</script>


<style>
/* 重写默认的一个样式 */
.rect-printElement-types .hiprint-printElement-type>li>ul>li>a {
  color: black !important;
  height: 48px !important;
}

.rect-printElement-types {
  background-color: white !important;
}

.custom-style-types {
  background-color: white !important;
}

/* 自定义 provider 构建样式 */
.custom-style-types .hiprint-printElement-type {
  display: block;
}

.custom-style-types .hiprint-printElement-type {
  padding: 0 0 0 0;
  list-style: none;
}

.custom-style-types .hiprint-printElement-type>li>.title {
  display: block;
  padding: 4px 0px;
  color: rgb(0, 58, 230);
  clear: both;
}

.custom-style-types .hiprint-printElement-type>li>ul {
  padding: 0 0 0 0;
  display: block;
  list-style: none;
}

.custom-style-types .hiprint-printElement-type>li>ul>li {
  display: block;
  width: 50%;
  float: left;
  max-width: 100px;
}

.custom-style-types .hiprint-printElement-type>li>ul>li>a {
  padding: 12px 6px;
  color: #1296db;
  text-decoration: none;
  background: #fff;
  border: 1px solid #ddd;
  margin-right: 5px;
  width: 95%;
  max-width: 100px;
  display: inline-block;
  text-align: center;
  margin-bottom: 7px;
  box-sizing: border-box;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.15);
}
</style>

<style scoped>
/* api按钮 */
.api {
  background: #00acc1;
}

.auto {
  width: auto !important;
}

/* 纸张 */
.paper {
  margin-right: 10px;
}

.paper button:not(class*="auto") {
  width: 60px !important;
}

/* 多个 button 间距 */
.paper button+button {
  margin-left: -1px;
}

.paper button:first-child:last-child {
  border-radius: 4px;
}

/* 两边的 btn 圆角 */
.paper button:first-child:not(:last-child) {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

.paper button:last-child:not(:first-child) {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

.popover {
  position: absolute;
  margin-top: 10px;
  z-index: 10;
}

.popover .popover-content {
  background: white;
  border-radius: 4px;
  padding: 10px 14px;
  box-shadow: 2px 2px 2px 4px rgb(128 0 128 / 20%);
}

.popover .input {
  height: 24px;
  padding: 2px 4px;
}

.popover .input:hover {
  border-color: rgb(245, 155, 241);
  border-radius: 4px;
}

/* 区域 */
.left {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.left .container {
  height: 50%;
  overflow: auto;
  padding: 0 10%;
  background: rgb(245, 155, 241);
}

.left .container[id*="provider-container2"] {
  margin-bottom: 10px;
  background: rgb(209, 120, 239);
}

.center {
  margin: 0 10px;
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 20px;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

.right {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}

/* 左侧拖拽元素样式 */
.title {
  font-size: 16px;
  font-weight: 500;
  margin: 4px 0 4px 10px;
}

.item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: white;
  padding: 4px 10px;
  margin: 10px 8px 4px 8px;
  width: 38%;
  min-height: 60px;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 2px rgba(171, 171, 171, 0.2);
}

.item .iconfont {
  font-size: 1.5rem;
}

.item span {
  font-size: 14px;
}
</style>

<style scoped></style>./use-zoom./template-helper./template-helper